<template>
  <div class="preview-container" v-if="processDefinition" v-loading="loading">
    <div
        style="width: 100%;text-align: center;font-size: 16px;margin-bottom: 12px;">
      <div v-if="basicSetting && basicSetting.flowName">
        {{ basicSetting.flowName }}
      </div>
    </div>
    <br>

    <el-form
        v-if="!loading"
        label-width="auto"
        class="formShow"
        :model="formValue"
        :rules="ruleList"
        :size="formData.size"
        :label-width="`${formData.labelWidth}px`"
        :label-position="formData.labelPosition || 'left'"
        ref="formRef"
    >
      <el-scrollbar>
        <RenderPreview :taskId="tid" v-if="formData" :formValue="formValue" ref="renderPreview"
                       :fields="formData.fields"
                       :processDesign="curNodeProcessDesign"/>
      </el-scrollbar>
      <FormRenderBtn :flowOperationBtnShow="flowOperationBtnShow"
                     @submitForm="submitForm"
                     :resetForm="resetForm"/>
    </el-form>
  </div>
</template>
<script setup name='FormRender'>
import RenderPreview from "@/views/flow/createDirectly/generatorForm/FormRender/RenderPreview.vue";
import {getDefinition} from "@/api/flow/definition.js";
import {getformFields, isNotEmptyArray} from "@/views/flow/tool.js";
import {ElNotification} from "element-plus";
import {getTaskDetail} from "@/api/flow/task.js";
import {G} from "@/views/flow/globalVar.js";
import FormRenderBtn from "@/views/flow/createDirectly/generatorForm/FormRender/FormRenderBtn.vue";
import {handleSubmit} from "@/views/flow/createDirectly/generatorForm/FormRender/handleSubmit.js";
const props = defineProps({
  taskId: {
    type: String,
    default: () => {
      return ''
    }
  },
  processDefinitionId: {
    type: String,
    default: () => {
      return ''
    }
  },
  //预览的时候，需要把 formData 传进来
  formData: {
    type: Object,
    default: () => {
      return undefined
    }
  }
})
const emit = defineEmits([
  'success'
]);
const flowOperationBtnShow = ref(undefined)
const ruleList = ref([]);
const formRef = ref(null);
const loading = ref(false)

const taskStatus = ref(G.TASK_STATUS.PREVIEW);
const flowStatus = ref(undefined);
const fcInputTable = ref([])
//表单结构
const formData = ref(undefined)
//表单值结构
const formValue = ref(undefined)
//当前节点信息，包括权限
const curNodeProcessDesign = ref(undefined)
//流程配置信息，例如表单名称
const basicSetting = ref(undefined)
//流程定义，包含 basicSetting 所有节点的 processDesign 以及 formData
const processDefinition = ref(undefined)
const processDefinitionId = ref(undefined)
const processInstancesId = ref(undefined)
const tid = ref(props.taskId)
const taskType = ref(undefined);
const renderPreview = ref(undefined)
const receiveFcInputTable = (ref) => {
  if (ref) {
    fcInputTable.value.push(ref)
  }
}
provide('receiveFcInputTable',
    receiveFcInputTable)
//审批
const getTaskData = async (detail) => {
  flowStatus.value = detail.data.flowStatus
  flowOperationBtnShow.value = detail.data.flowOperationBtnShow
  taskStatus.value = detail.data.taskStatus
  taskType.value = detail.data.taskType

  processInstancesId.value = detail.data.processInstancesId
  processDefinitionId.value = detail.data.processDefinitionId
  processDefinition.value = JSON.parse(detail.data.json)
  formData.value = processDefinition.value.formData
  formValue.value = processDefinition.value.formValue
  basicSetting.value = processDefinition.value.basicSetting
  //当前节点的信息
  curNodeProcessDesign.value = processDefinition.value.curNodeProcessDesign
}
//发起
const getLaunchData = async (detail) => {
  flowStatus.value = undefined
  taskStatus.value = undefined
  processDefinitionId.value = detail.data.processDefinitionId
  flowOperationBtnShow.value = detail.data.flowOperationBtnShow
  processDefinition.value = JSON.parse(detail.data.json)
  formData.value = processDefinition.value.formData
  curNodeProcessDesign.value = processDefinition.value.processData
  basicSetting.value = processDefinition.value.basicSetting
  //设置表单vModel结构
  let formFields = []
  getformFields(formData.value.fields,
      formFields)
  let objValues = {}
  formFields.forEach((item) => {
    objValues[item.vModel] = undefined
  })
  formValue.value = JSON.parse(JSON.stringify(objValues))
}
//预览
const getPreviewData = () => {
  flowStatus.value = undefined
  taskType.value = undefined
  formData.value = props.formData

  //打散字段
  let formFields = []
  getformFields(formData.value.fields,
      formFields)
  //设置权限
  processDefinition.value = {
    processDesign: {
      properties: {
        formOperates: formFields.map((res) => {
          return {
            formId: res.formId,
            formOperate: G.FORM_OPERATE.EDIT,
            label: res.label,
            required: true,
            vModel: res.vModel
          }
        })
      }
    }
  }
  //设置表单vModel结构
  let objValues = {}
  formFields.forEach((item) => {
    objValues[item.vModel] = undefined
  })
  formValue.value = JSON.parse(JSON.stringify(objValues))
  curNodeProcessDesign.value = processDefinition.value.processDesign
}
const init = async ({
                      taskId,
                      processDefinitionId
                    }) => {
  loading.value = true;
  //有任务id
  if (!!taskId) {
    const detail = await getTaskDetail({curTaskId: taskId})
    await getTaskData(detail)
  }
  //发起流程
  else if (processDefinitionId) {
    const detail = await getTaskDetail({processDefinitionId: processDefinitionId})
    await getLaunchData(detail)
  }
  //预览
  else if (taskStatus.value == G.TASK_STATUS.PREVIEW) {
    getPreviewData()
  }
  loading.value = false;
}
onMounted(async () => {
  init({
    taskId: tid.value,
    processDefinitionId: props.processDefinitionId
  })
})
/*table校验*/
const checkTableData = () => {
  let valid = true
  if (isNotEmptyArray(fcInputTable.value)) {
    for (let i = 0; i < fcInputTable.value.length; i++) {
      if (!fcInputTable.value[i].submit()) {
        valid = false
        break
      }
    }
  }
  return valid
}
const finishApproval = async (res) => {
  //
  tid.value = res.data.ID;
  processDefinitionId.value = res.data.processDefinitionId;
  processInstancesId.value = res.data.processInstancesId;
  //审批完成，可编辑的字段，改成只读
  if (curNodeProcessDesign.value && [
    G.TASK_STATUS.RE_SUBMIT_ALL,
    G.TASK_STATUS.RE_SUBMIT,
    G.TASK_STATUS.APPROVAL,
    G.TASK_STATUS.INITIATE_APPLICATION,
    G.TASK_STATUS.REJECT_AND_END,
    G.TASK_STATUS.RETURNED,
    G.TASK_STATUS.RETURNED_ALL,
  ].includes(parseInt(res.data.taskStatus))) {
    let value = JSON.parse(JSON.stringify(curNodeProcessDesign.value))
    value.properties.formOperates = value.properties.formOperates.map((res) => {
      if (res.formOperate == G.FORM_OPERATE.EDIT) {
        res.formOperate = G.FORM_OPERATE.READ
      }
      return res
    })
    curNodeProcessDesign.value = value
  }
}
/* 表单提交 */
const submitForm = async ({operation}) => {
  loading.value = true;
  try {
    const isTableValid = checkTableData();
    // 用 Promise 包一下 validate
    const isFormValid = await new Promise((resolve) => {
      formRef.value.validate((valid) => {
        resolve(valid);
      });
    });
    if (!isFormValid || !isTableValid) {
      loading.value = false;
      return;
    }
    // 正确地 await handleSubmit，拿到 res
    const res = await handleSubmit({
      formValue: formValue.value,
      operation,
      processDefinitionId: processDefinitionId.value,
      taskId: tid.value,
      processInstancesId: processInstancesId.value,
    });
    await getTaskData(res)
    await finishApproval(res);
    emit('success',
        res);
    ElNotification.success('表单提交成功！');
  } catch (error) {
    console.error('提交失败',
        error);
    ElNotification.error('提交失败，请稍后重试');
  } finally {
    loading.value = false;
  }
};
const resetForm = () => {
  emit('resetForm');
};
</script>
<style lang='scss'>
.preview-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  overflow: hidden;
  .formShow {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    overflow: hidden;
    background: #fff;
    .el-scrollbar {
      width: 100%;
    }
  }
}
</style>
